package com.xhj.api;


import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.gson.Gson;
import com.xhj.entity.Member;
import com.xhj.service.MemberService;
import com.xhj.util.ConstantProperties;
import com.xhj.util.HttpClientUtils;
import com.xhj.util.JwtUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpSession;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@CrossOrigin
@Controller
@RequestMapping("/api/ucenter/wx")
@Slf4j
public class WxApiController {

    @Autowired
    private ConstantProperties constantProperties;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private MemberService memberService;

    @ApiOperation(value = "生成微信登录二维码并登录")
    @RequestMapping("login")
    public String genQrConnect(HttpSession session){
        // 微信开放平台授权baseUrl
        String baseUrl = "https://open.weixin.qq.com/connect/qrconnect" +
            "?appid=%s" +
            "&redirect_uri=%s" +
            "&response_type=code" +
            "&scope=snsapi_login" +
            "&state=%s" +
            "#wechat_redirect";
        // 回调地址
        String redirectUrl = constantProperties.getRedirectUrl();
        try {
            redirectUrl = URLEncoder.encode(redirectUrl, "UTF-8");
        }catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }
        // 用UUID和sessionId构造state,防止csrf攻击
        String state = UUID.randomUUID().toString().replaceAll("-", "");
        // 将state存入Redis中，以便验证
        String sessionId = session.getId();
        redisTemplate.opsForValue().set("state-key-" + sessionId,state,120, TimeUnit.MINUTES);

        String url = String.format(baseUrl, constantProperties.getAppId(), redirectUrl, state);
        return "redirect:" + url;
    }

    @RequestMapping("callback")
    public String callback(String code,String state,HttpSession session){
        if (StringUtils.isEmpty(code)) throw new RuntimeException("请扫码登录！");
        // 取出Redis中state验证，防止csrf攻击
        String stateInRedis = redisTemplate.opsForValue().get("state-key-" + session.getId());
        assert stateInRedis != null;
        if (!stateInRedis.equals(state)) throw new RuntimeException("error");
        // 向认证服务器发送请求换取access_token
        String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token"
                + "?appid=%s"
                + "&secret=%s"
                + "&code=%s"
                + "&grant_type=authorization_code";
        String accessTokenUrl = String.format(baseAccessTokenUrl,
                constantProperties.getAppId(),
                constantProperties.getAppSecret(),
                code);

        String result = null;
        try {
            result = HttpClientUtils.get(accessTokenUrl);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("获取access_token失败");
        }

        Gson gson = new Gson();
        HashMap<String, Object> map = gson.fromJson(result, HashMap.class);
        // 获取access_token
        String access_token = (String) map.get("access_token");
        String openid = (String) map.get("openid");
        // 查询数据库当前用用户是否曾经使用过微信登录
        Member member = memberService.getByOpenId(openid);
        if (member == null){
            // 获取微信用户信息
            String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo"
                    + "?access_token=%s"
                    + "&openid=%s";
            String userInfoUrl = String.format(baseUserInfoUrl,access_token,openid);

            String userInfoResult = null;
            try {
                userInfoResult = HttpClientUtils.get(userInfoUrl);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("获取用户信息失败！");
            }

            HashMap<String, Object> userInfo = gson.fromJson(userInfoResult, HashMap.class);
            String nickname = (String) userInfo.get("nickname");
            String avatar = (String) userInfo.get("headimgurl");

            member = new Member();
            member.setNickname(nickname);
            member.setOpenid(openid);
            member.setAvatar(avatar);
            memberService.save(member);

        }
        // 生成jwt
        String jwtToken = JwtUtil.getJwtToken(member.getId(), member.getNickname());

        return "redirect:http://localhost:3000?token=" + jwtToken;
    }
}
